package swim2.sessionbeans;


import java.util.*;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import swim2.entitybeans.*;

import org.jboss.ejb3.annotation.RemoteBinding;


@Stateless
@RemoteBinding(jndiBinding="swim2JNDI")
public class LoginSystem implements LoginSystemRemote{
	
	@PersistenceContext(unitName="swim2") private EntityManager manager;
	
	/**
	 * Metodo invocato quando un utente tenta di effettuare il login.
	 * Il sistema cerca nel database se la mail inserita e' presente nel database,
	 * e, in caso affermativo, verifica che la password sia corretta.
	 * @param mail: la mail inserita dall'utente nella form di login.
	 * @param password: la password inserita dall'utente nella form di login.
	 * @return: l'id dell'utente se il login viene effettuato correttamente, -1 se
	 * 			l'utente non e' registrato o se la password e' errata.
	 */
	public int getAuthentication(String mail, String password){
		Query q = manager.createQuery("SELECT u FROM User u WHERE u.mail=:mail");
		q.setParameter("mail", mail);
		if(q.getResultList().size()==0) return -1;
		User user = (User) q.getSingleResult();
		if(user.getPassword().equals(password)) return user.getId();
		return -1;	
	}
	
	/**
	 * Verifica se un utente e' un admin o un semplice utente.
	 * @param id: l'id dell'utente.
	 * @return: 'true' se l'utente e' un admin, 'false' altrimenti.
	 */
	public boolean isAdmin(int id) {
		Query q = manager.createQuery("SELECT u.isadmin FROM User u WHERE u.id=:id");
		q.setParameter("id", id);
		return (Boolean) q.getSingleResult();
	}
	
	/**
	 * Inserisce un nuovo utente nel database.
	 * @param mail: la mail inserita dall'utente nella form di registrazione.
	 * @param password: la password inserita dall'utente nella form di registrazione.
	 * @param ability: il nome dell'abilita' selezionata dall'utente nella form di registrazione.
	 * @param name: il nome inserito dall'utente nella form di registrazione.
	 * @param surname: il cognome inserito dall'utente nella form di registrazione.
	 * @return: l'id dell'utente se la registrazione viene effettuata correttamente; -2 se la mail
	 * 			inserita risulta gia' utilizzata; -1 se si verifica qualche eccezione.
	 */
	public int insertUser(String mail, String password, String ability, String name, String surname) {
		try{
			Query q = manager.createQuery("SELECT u.id FROM User u WHERE u.mail=:mail");
			q.setParameter("mail", mail);
			if(mail==null || password==null || name==null || surname==null) return -3;
			if(q.getResultList().size()==0) {
				User user = new User(mail, password);
				user.setName(name);
				user.setSurname(surname);
				manager.persist(user);
				Query r = manager.createQuery("SELECT a.id FROM Ability a WHERE a.name=:ability");
				r.setParameter("ability", ability); 
				int abilityId = (Integer) r.getResultList().get(0);
				UserAbility ua = new UserAbility(user.getId(), abilityId);
				manager.persist(ua);
				return user.getId();
			}
			else return -2;
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		return -1;
	}
	
	/**
	 * Ottiene la lista di tutte le abilita' presenti nel database.
	 * @return: un ArrayList di stringhe contenente i nomi di tutte le abilita' presenti nel DB.
	 */
	public ArrayList<String> getAbilities(){
		try {
			Query q = manager.createQuery("SELECT a.name FROM Ability a");
			ArrayList<String> abilities = (ArrayList<String>) q.getResultList();
			Collections.sort(abilities);
			return abilities;
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * Rende amministratore un determinato utente.
	 * @param mail: la mail dell'utente da rendere admin.
	 * @param password: la password dell'utente da rendere admin.
	 * @return: l'id dell'utente se l'operazione e' andata a buon fine; -1 altrimenti.
	 */
	public int insertAdmin(String mail, String password) {
		try {
		User user = new User(mail, password);
		user.setAdmin(true);
		manager.persist(user);
		return user.getId();
		}
		catch (Exception e) {
			
		}
		return -1;
	}
}
